! git log -1 --format="%H"
aa9dbe508f9a5c056061345264537c2844a78a74
import sys
# Install gurobi
!{sys.executable} -m pip install -i https://pypi.gurobi.com gurobipy
!{sys.executable} -m pip install plotly geopy
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pandas as pd
from itertools import product
import gurobipy as gp
from gurobipy import GRB, quicksum
# These are ours
import problem
import visualization
Looking in indexes: https://pypi.gurobi.com Requirement already satisfied: gurobipy in /opt/anaconda3/lib/python3.8/site-packages (9.1.1) Requirement already satisfied: plotly in /opt/anaconda3/lib/python3.8/site-packages (4.14.3) Requirement already satisfied: geopy in /opt/anaconda3/lib/python3.8/site-packages (2.1.0) Requirement already satisfied: six in /opt/anaconda3/lib/python3.8/site-packages (from plotly) (1.15.0) Requirement already satisfied: retrying>=1.3.3 in /opt/anaconda3/lib/python3.8/site-packages (from plotly) (1.3.3) Requirement already satisfied: geographiclib<2,>=1.49 in /opt/anaconda3/lib/python3.8/site-packages (from geopy) (1.50)
def normalize(i, j):
assert i != j
return (i, j) if i < j else (j, i)
from model import Autonomax, Config
# Run on the first |C| cities (mostly for testing)
C = 41
# What scenario we will be utilizing
scenario = 0
# The number of cities in the core net
NC = 7
# 1 if the core net should be a cycle; 0 if it shoul be a path.
Z = 1
autonomax = Autonomax(
Config(
cities=problem.cities[:C],
distances=problem.D[:C, :C],
demand=problem.B[scenario][:C],
core_city_count=NC,
core_net_is_cycle=Z,
)
)
Academic license - for non-commercial use only - expires 2021-05-15 Using license file /Users/sjurwold/gurobi.lic
A = autonomax.model.getA()
count = lambda d: len(d) if isinstance(d, gp.tupledict) else 1
V = sum(count(v) for v in autonomax.variables.values())
C = sum(count(c) for c in autonomax.constraints.values())
print(f'V = {V}, C = {C}')
fig, ax = plt.subplots(1, figsize=(128, 128 * C/V))
ax.set_xticklabels([])
ax.set_yticklabels([])
plt.spy(A)
total = 0
print(f'\nCONSTRAINT SETS:')
for (name, constraint) in autonomax.constraints.items():
constraints_in_set = count(constraint)
print(f'{constraints_in_set:>5} | {name}')
#plt.gcf().text(0.07, 0.69 - 0.4 * (total + 0.5 * count(constraint)) / C, name, fontsize=14)
total += constraints_in_set
plt.plot([0, V], [total - 0.5, total - 0.5], color='grey')
total = 0
print(f'\nVARIABLE SETS:')
for (name, variables) in autonomax.variables.items():
variables_in_set = count(variables)
print(f'{variables_in_set:>5} | {name}')
#plt.gcf().text(0.1 + 0.8 * (total + 0.5*count(variables)) / V, 0.8, name, fontsize=14)
total += count(variables)
plt.plot([total - 0.5, total - 0.5], [0, C], color='grey')
plt.savefig('constraint-matrix.png', dpi=200)
V = 14555, C = 8736
CONSTRAINT SETS:
1 | one_control_center
41 | control_city_directly_connected
1681 | reduce_control_center_symmetry
41 | core_city_ub
1 | cycle_or_path
41 | disallow_core_tree
1 | exactly_nc_core_cities
41 | control_center_is_connected
4920 | is_connectable
246 | is_connected_timestep
41 | connected_graph
41 | conservation_of_flow
820 | force_edge_if_flow
820 | edge_cost_lb
VARIABLE SETS:
41 | is_control_center
820 | is_core_edge
41 | is_core_city
287 | is_connected_step
10086 | is_connectable_step
820 | flow
820 | abs_flow
820 | is_sub_edge
820 | edge_cost
autonomax.model.Params.timeLimit = 600.0
autonomax.model.optimize()
Changed value of parameter timeLimit to 600.0
Prev: inf Min: 0.0 Max: inf Default: inf
Gurobi Optimizer version 9.1.1 build v9.1.1rc0 (mac64)
Thread count: 8 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 8736 rows, 14555 columns and 45305 nonzeros
Model fingerprint: 0x02ec7352
Model has 7 SOS constraints
Model has 820 general constraints
Variable types: 2460 continuous, 12095 integer (12095 binary)
Coefficient statistics:
Matrix range [1e+00, 2e+05]
Objective range [1e+00, 2e+04]
Bounds range [1e+00, 1e+02]
RHS range [7e-01, 4e+01]
Presolve removed 105 rows and 5234 columns
Presolve time: 0.14s
Presolved: 8631 rows, 9321 columns, 45033 nonzeros
Variable types: 2460 continuous, 6861 integer (6861 binary)
Found heuristic solution: objective 138513.73870
Root relaxation: objective 2.824799e+03, 4466 iterations, 0.19 seconds
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 2824.79862 0 188 138513.739 2824.79862 98.0% - 0s
H 0 0 52549.920520 2824.79862 94.6% - 0s
H 0 0 41045.829979 2824.79862 93.1% - 0s
0 0 4894.10752 0 278 41045.8300 4894.10752 88.1% - 0s
H 0 0 40713.307468 4894.10752 88.0% - 1s
0 0 5068.73820 0 350 40713.3075 5068.73820 87.6% - 1s
0 0 5079.46033 0 280 40713.3075 5079.46033 87.5% - 1s
0 0 5079.46033 0 283 40713.3075 5079.46033 87.5% - 1s
0 0 5088.32254 0 478 40713.3075 5088.32254 87.5% - 1s
H 0 0 36834.112041 5088.32254 86.2% - 1s
0 0 5088.32254 0 414 36834.1120 5088.32254 86.2% - 1s
0 0 5090.60156 0 368 36834.1120 5090.60156 86.2% - 1s
0 0 5095.94818 0 340 36834.1120 5095.94818 86.2% - 1s
0 0 5096.21255 0 335 36834.1120 5096.21255 86.2% - 1s
0 0 5104.58306 0 425 36834.1120 5104.58306 86.1% - 2s
H 0 0 36828.573287 5104.58306 86.1% - 2s
0 0 5105.24241 0 410 36828.5733 5105.24241 86.1% - 2s
0 0 5105.53112 0 394 36828.5733 5105.53112 86.1% - 2s
H 0 0 36595.215081 5105.53112 86.0% - 2s
0 0 5106.08077 0 359 36595.2151 5106.08077 86.0% - 2s
H 0 0 36182.221198 5106.08077 85.9% - 2s
0 0 5106.68661 0 398 36182.2212 5106.68661 85.9% - 2s
0 0 5106.68661 0 271 36182.2212 5106.68661 85.9% - 2s
H 0 0 19341.815138 5106.68661 73.6% - 3s
H 0 0 19315.609619 5106.70055 73.6% - 3s
H 0 2 19288.338536 5106.70055 73.5% - 3s
0 2 5106.70055 0 271 19288.3385 5106.70055 73.5% - 3s
H 31 40 19268.338536 5361.73650 72.2% 642 4s
H 31 40 19196.586967 5361.73650 72.1% 642 4s
H 36 40 18932.254163 5361.73650 71.7% 592 4s
H 70 79 18912.254163 5361.73650 71.6% 426 4s
H 70 79 18846.022644 5361.73650 71.5% 426 4s
H 106 115 18836.022644 5361.73650 71.5% 337 5s
H 106 115 18721.130854 5361.73650 71.4% 337 5s
H 157 181 18711.130853 5361.73650 71.3% 261 5s
H 387 390 18690.925654 5361.73650 71.3% 149 7s
H 391 390 18631.837651 5361.73650 71.2% 148 7s
H 393 390 18162.442094 5361.73650 70.5% 148 7s
H 398 405 17950.716583 5361.73650 70.1% 151 7s
H 1005 973 17910.782850 5430.46375 69.7% 110 9s
1368 1325 8021.48859 48 272 17910.7829 5430.46375 69.7% 99.2 10s
H 1432 1342 17895.597273 5430.46375 69.7% 99.2 10s
1455 1344 14644.9723 160 216 17895.5973 5430.46375 69.7% 98.9 15s
H 1465 1283 17875.081294 5430.46375 69.6% 98.2 18s
H 1465 1218 17865.081294 5430.46375 69.6% 98.2 18s
1470 1221 16002.2347 167 431 17865.0813 5430.46375 69.6% 97.9 20s
1480 1228 8416.09583 20 422 17865.0813 5430.46375 69.6% 97.2 25s
H 1480 1166 17036.228483 5430.46375 68.1% 97.2 25s
H 1486 1111 17017.900070 5430.46375 68.1% 96.8 28s
H 1486 1055 17010.620733 5430.46375 68.1% 96.8 28s
H 1487 1005 16941.601941 5430.46375 67.9% 143 28s
1488 1006 5430.46375 13 356 16941.6019 5430.46375 67.9% 145 34s
1490 1009 5535.88266 14 387 16941.6019 5535.88266 67.3% 146 39s
1494 1011 5588.19645 15 332 16941.6019 5588.19645 67.0% 151 42s
1509 1021 5815.09801 17 356 16941.6019 5656.31539 66.6% 162 45s
H 1517 976 16931.601941 5684.13899 66.4% 171 47s
H 1520 927 16914.903909 5684.13899 66.4% 175 47s
1543 941 6046.51894 19 324 16914.9039 5684.13899 66.4% 187 50s
H 1554 899 16844.080058 5684.13899 66.3% 190 51s
1590 914 6698.14359 21 335 16844.0801 5684.13899 66.3% 206 55s
1712 977 7037.09115 26 323 16844.0801 5684.13899 66.3% 223 60s
1853 1036 cutoff 35 16844.0801 5684.13899 66.3% 235 65s
2000 1096 7364.13141 46 282 16844.0801 5684.13899 66.3% 244 70s
2269 1218 cutoff 60 16844.0801 5684.13899 66.3% 249 75s
2540 1255 cutoff 77 16844.0801 5684.13899 66.3% 250 80s
2872 1344 14956.5495 93 171 16844.0801 5684.13899 66.3% 257 86s
3125 1355 8271.33251 20 312 16844.0801 6719.20421 60.1% 265 91s
3273 1388 10396.1436 35 195 16844.0801 6719.20421 60.1% 271 95s
3577 1492 12489.9871 19 257 16844.0801 7377.17761 56.2% 273 101s
3766 1518 12650.9773 27 190 16844.0801 7493.11751 55.5% 280 105s
4118 1664 16709.0349 28 289 16844.0801 7637.96783 54.7% 280 111s
4429 1929 9593.53467 34 247 16844.0801 7637.96783 54.7% 276 116s
4688 2045 10213.5361 55 239 16844.0801 7917.00754 53.0% 275 122s
4879 2175 8154.24925 55 283 16844.0801 7944.83592 52.8% 276 125s
5193 2392 cutoff 58 16844.0801 7944.83592 52.8% 274 130s
H 5521 2453 16780.553067 7944.83592 52.7% 272 133s
5584 2543 15910.9701 90 118 16780.5531 8134.80129 51.5% 272 137s
H 5594 2535 16741.222923 8134.80129 51.4% 272 137s
5794 2624 8466.96668 23 314 16741.2229 8278.94069 50.5% 273 140s
6153 2831 cutoff 29 16741.2229 8278.94069 50.5% 274 146s
6358 2960 15775.5195 33 268 16741.2229 8395.98631 49.8% 273 150s
6608 2996 11619.9847 29 267 16741.2229 8395.98631 49.8% 270 158s
H 6645 2996 16741.222918 8395.98631 49.8% 270 158s
6694 3120 15958.6522 30 256 16741.2229 8560.39141 48.9% 270 161s
6916 3237 11031.9269 42 166 16741.2229 8609.03525 48.6% 271 165s
H 7214 3317 16741.222914 8661.05117 48.3% 274 168s
7363 3427 10631.0901 45 191 16741.2229 8682.80589 48.1% 277 172s
7662 3587 cutoff 55 16741.2229 8748.18907 47.7% 277 176s
7981 3714 16142.6818 106 126 16741.2229 8761.34780 47.7% 277 180s
8251 3968 11977.6263 26 267 16741.2229 8813.22816 47.4% 279 185s
8797 4244 9426.85079 26 363 16741.2229 8905.67876 46.8% 279 194s
9112 4401 cutoff 25 16741.2229 8930.77323 46.7% 280 198s
9478 4506 10565.4941 42 259 16741.2229 9049.24203 45.9% 283 203s
9778 4524 13811.3224 45 193 16741.2229 9155.15246 45.3% 284 209s
H 9781 4524 16741.222894 9155.15246 45.3% 284 209s
9842 4712 13710.7148 25 341 16741.2229 9167.27794 45.2% 285 215s
10227 4950 9931.39780 52 334 16741.2229 9223.77059 44.9% 286 221s
10642 5157 15215.0129 47 151 16741.2229 9302.52570 44.4% 285 243s
H11007 5309 16741.222891 9324.69402 44.3% 287 248s
H11021 5309 16741.222885 9341.06791 44.2% 288 248s
11371 5403 11851.3530 87 288 16741.2229 9403.69584 43.8% 290 254s
11606 5617 infeasible 122 16741.2229 9464.74911 43.5% 289 261s
H11610 5617 16741.222875 9464.74911 43.5% 289 261s
12109 5783 15659.8123 46 324 16741.2229 9537.42730 43.0% 289 267s
12531 5876 12000.0470 59 248 16741.2229 9696.88360 42.1% 292 274s
12760 6171 11076.0064 31 266 16741.2229 9759.27877 41.7% 293 280s
H13290 6171 16741.222807 9778.92730 41.6% 291 280s
13400 6312 15825.0453 71 153 16741.2228 9805.20077 41.4% 291 288s
H13512 6312 16741.222793 9807.12183 41.4% 291 288s
13843 6438 10252.9662 20 304 16741.2228 9912.82056 40.8% 292 295s
H13908 6438 16741.222781 9912.82056 40.8% 292 295s
H14296 6628 16741.222761 9995.77943 40.3% 294 302s
H14357 6628 16741.222757 10001.0452 40.3% 295 302s
H14438 6628 16741.222721 10001.0452 40.3% 294 302s
14769 6917 13789.5345 40 369 16741.2227 10055.3551 39.9% 297 312s
H15008 6917 16741.222695 10097.6574 39.7% 297 312s
15443 7137 13533.7524 27 265 16741.2227 10154.6849 39.3% 297 319s
15895 7344 infeasible 50 16741.2227 10173.4657 39.2% 299 328s
H16254 7344 16741.222649 10188.1571 39.1% 299 328s
16538 7627 14250.2484 32 208 16741.2226 10225.4652 38.9% 298 336s
17158 7754 16497.4242 28 233 16741.2226 10302.5841 38.5% 299 346s
17528 7914 cutoff 36 16741.2226 10318.5321 38.4% 301 356s
18099 8192 cutoff 33 16741.2226 10406.4902 37.8% 304 366s
18848 8349 16560.4459 32 324 16741.2226 10488.3491 37.4% 306 376s
19317 8677 cutoff 43 16741.2226 10532.1670 37.1% 308 494s
20120 8826 11848.9896 47 246 16741.2226 10593.3452 36.7% 309 505s
20488 9193 12217.2845 49 305 16741.2226 10653.1892 36.4% 310 518s
21283 9525 12396.1646 37 209 16741.2226 10710.8928 36.0% 309 531s
22174 9935 15704.4983 59 197 16741.2226 10738.0137 35.9% 311 543s
23148 10148 12314.8839 65 245 16741.2226 10833.4075 35.3% 311 556s
23884 10422 11653.5952 40 289 16741.2226 10869.4083 35.1% 312 569s
24794 10855 cutoff 33 16741.2226 10955.0521 34.6% 312 583s
25909 11113 14842.1567 50 180 16741.2226 10994.0293 34.3% 310 595s
26725 11220 cutoff 30 16741.2226 11063.5132 33.9% 311 600s
Cutting planes:
Gomory: 32
Cover: 1453
MIR: 308
Flow cover: 841
GUB cover: 72
Inf proof: 8
Zero half: 78
RLT: 309
Relax-and-lift: 7
Explored 27061 nodes (8445871 simplex iterations) in 600.01 seconds
Thread count was 8 (of 8 available processors)
Solution count 10: 16741.2 16741.2 16741.2 ... 16741.2
Time limit reached
Best objective 1.674122264862e+04, best bound 1.109345534172e+04, gap 33.7357%
city_info = pd.DataFrame(autonomax.city_info())
city_info
| Index | Name | IsCoreCity | IsControlCenter | Demand | IngoingFlow | OutgoingFlow | |
|---|---|---|---|---|---|---|---|
| 0 | 0 | Boden | False | False | 4.5 | 4.000000e+00 | 8.500000 |
| 1 | 1 | Borås | False | False | 0.7 | 1.610000e+01 | 16.800000 |
| 2 | 2 | Eskilstuna | True | False | 1.1 | 6.890000e+01 | 70.000000 |
| 3 | 3 | Falun | False | False | 2.3 | 5.258016e-13 | 2.300000 |
| 4 | 4 | Gävle | False | False | 1.0 | 3.130000e+01 | 32.300001 |
| 5 | 5 | Göteborg | False | False | 5.8 | 1.163514e-12 | 5.800000 |
| 6 | 6 | Halmstad | False | False | 3.4 | 6.100000e+00 | 9.500000 |
| 7 | 7 | Haparanda | False | False | 4.6 | 0.000000e+00 | 4.600000 |
| 8 | 8 | Helsingborg | False | False | 2.2 | 3.900000e+00 | 6.100000 |
| 9 | 9 | Hudiksvall | False | False | 3.9 | 2.740000e+01 | 31.299999 |
| 10 | 10 | Jönköping | True | False | 1.2 | 4.610000e+01 | 47.300000 |
| 11 | 11 | Kalmar | False | False | 4.0 | 5.608847e-13 | 4.000000 |
| 12 | 12 | Karlskrona | False | False | 1.6 | 1.278977e-13 | 1.600000 |
| 13 | 13 | Karlstad | False | False | 0.9 | 5.044853e-13 | 0.900000 |
| 14 | 14 | Kiruna | False | False | 4.0 | 1.278977e-13 | 4.000000 |
| 15 | 15 | Kristianstad | False | False | 3.0 | 4.618528e-13 | 3.000000 |
| 16 | 16 | Lidköping | False | False | 1.2 | 7.600000e+00 | 8.800000 |
| 17 | 17 | Linköping | True | False | 4.1 | 5.150000e+01 | 55.600000 |
| 18 | 18 | Luleå | False | False | 2.0 | 1.310000e+01 | 15.100000 |
| 19 | 19 | Malmö | False | False | 2.6 | 1.300000e+00 | 3.900000 |
| 20 | 20 | Motala | False | False | 2.4 | 4.013686e-07 | 2.400000 |
| 21 | 21 | Norrköping | True | False | 1.7 | 6.020000e+01 | 61.900000 |
| 22 | 22 | Nyköping | False | False | 4.6 | 3.966553e-07 | 4.600000 |
| 23 | 23 | Sandviken | False | False | 4.5 | 9.094947e-13 | 4.500000 |
| 24 | 24 | Skellefteå | False | False | 4.4 | 1.510000e+01 | 19.500000 |
| 25 | 25 | Skövde | True | False | 2.5 | 1.380000e+01 | 16.300000 |
| 26 | 26 | Stockholm | False | False | 7.0 | 1.205221e-06 | 7.000001 |
| 27 | 27 | Sundsvall | False | False | 0.7 | 2.670000e+01 | 27.399999 |
| 28 | 28 | Trelleborg | False | False | 1.3 | 1.094236e-12 | 1.300000 |
| 29 | 29 | Uddevalla | False | False | 4.0 | 7.538503e-11 | 4.000000 |
| 30 | 30 | Umeå | False | False | 3.2 | 1.950000e+01 | 22.700000 |
| 31 | 31 | Uppsala | False | False | 1.9 | 3.230000e+01 | 34.200000 |
| 32 | 32 | Varberg | False | False | 0.8 | 9.500000e+00 | 10.300000 |
| 33 | 33 | Vetlanda | False | False | 2.1 | 1.090000e+01 | 13.000000 |
| 34 | 34 | Vänersborg | False | False | 3.6 | 4.000000e+00 | 7.600000 |
| 35 | 35 | Västervik | False | False | 1.8 | 5.929479e-12 | 1.800000 |
| 36 | 36 | Västerås | True | False | 1.4 | 1.110000e+02 | 112.400000 |
| 37 | 37 | Växjö | False | False | 2.3 | 4.600000e+00 | 6.900000 |
| 38 | 38 | Örebro | True | True | 4.1 | 1.133000e+02 | 5.000000 |
| 39 | 39 | Örnsköldsvik | False | False | 3.1 | 2.270000e+01 | 25.799999 |
| 40 | 40 | Östersund | False | False | 0.9 | 1.271871e-12 | 0.900000 |
edge_info = pd.DataFrame(autonomax.edge_info())
edge_info
| From | To | Type | Flow | Cost | Distance | |
|---|---|---|---|---|---|---|
| 0 | Skellefteå | Umeå | SUB | 19.500000 | 731.139145 | 111 |
| 1 | Eskilstuna | Västerås | CORE | 70.000000 | 430.000000 | 43 |
| 2 | Skövde | Örebro | CORE | -5.000000 | 1320.000000 | 132 |
| 3 | Gävle | Hudiksvall | SUB | -31.299999 | 1278.724532 | 118 |
| 4 | Norrköping | Nyköping | SUB | -4.600000 | 74.253949 | 58 |
| 5 | Linköping | Norrköping | CORE | 55.600000 | 440.000000 | 44 |
| 6 | Karlskrona | Växjö | SUB | 1.600000 | 62.121900 | 102 |
| 7 | Boden | Kiruna | SUB | -4.000000 | 637.912937 | 291 |
| 8 | Jönköping | Skövde | CORE | -16.300000 | 810.000000 | 81 |
| 9 | Sundsvall | Östersund | SUB | -0.900000 | 70.870188 | 166 |
| 10 | Eskilstuna | Stockholm | SUB | -7.000000 | 234.688115 | 101 |
| 11 | Halmstad | Helsingborg | SUB | -6.100000 | 145.447337 | 79 |
| 12 | Jönköping | Vetlanda | SUB | -13.000000 | 225.433574 | 65 |
| 13 | Umeå | Örnsköldsvik | SUB | 22.699999 | 849.479930 | 111 |
| 14 | Lidköping | Skövde | SUB | 8.800000 | 105.450189 | 49 |
| 15 | Karlstad | Örebro | SUB | 0.900000 | 29.229961 | 77 |
| 16 | Halmstad | Varberg | SUB | 9.500000 | 167.432227 | 65 |
| 17 | Lidköping | Vänersborg | SUB | -7.600000 | 121.696732 | 60 |
| 18 | Uddevalla | Vänersborg | SUB | 4.000000 | 22.172756 | 21 |
| 19 | Hudiksvall | Sundsvall | SUB | -27.399999 | 641.652295 | 81 |
| 20 | Linköping | Motala | SUB | -2.400000 | 37.641812 | 51 |
| 21 | Sandviken | Västerås | SUB | 4.500000 | 174.172912 | 110 |
| 22 | Borås | Göteborg | SUB | -5.800000 | 119.727508 | 71 |
| 23 | Falun | Västerås | SUB | 2.299999 | 115.327709 | 128 |
| 24 | Jönköping | Linköping | CORE | 47.300000 | 1250.000000 | 125 |
| 25 | Linköping | Västervik | SUB | -1.800000 | 64.378849 | 97 |
| 26 | Sundsvall | Örnsköldsvik | SUB | -25.799999 | 1177.683851 | 127 |
| 27 | Vetlanda | Växjö | SUB | -6.900000 | 143.305429 | 72 |
| 28 | Borås | Varberg | SUB | -10.300000 | 260.758783 | 84 |
| 29 | Haparanda | Luleå | SUB | 4.600000 | 210.858567 | 124 |
| 30 | Luleå | Skellefteå | SUB | 15.100000 | 742.410222 | 133 |
| 31 | Kristianstad | Växjö | SUB | 3.000000 | 134.707658 | 120 |
| 32 | Uppsala | Västerås | SUB | 34.200000 | 755.020135 | 78 |
| 33 | Gävle | Uppsala | SUB | 32.300000 | 484.711112 | 60 |
| 34 | Helsingborg | Malmö | SUB | -3.900000 | 67.318060 | 60 |
| 35 | Västerås | Örebro | CORE | 112.400000 | 930.000000 | 93 |
| 36 | Borås | Jönköping | SUB | 16.800000 | 404.484606 | 82 |
| 37 | Boden | Luleå | SUB | 8.500000 | 58.656837 | 32 |
| 38 | Malmö | Trelleborg | SUB | -1.300000 | 18.150077 | 34 |
| 39 | Eskilstuna | Norrköping | CORE | -61.900000 | 1020.000000 | 102 |
| 40 | Kalmar | Vetlanda | SUB | 4.000000 | 174.202753 | 119 |
core_cost = sum(edge_info[edge_info['Type'] == 'CORE']['Cost'])
subnet_cost = sum(edge_info[edge_info['Type'] == 'SUB']['Cost'])
total_cost = core_cost + subnet_cost
print(f'core = {core_cost:>9.3f}')
print(f'subnet = {subnet_cost:>9.3f}')
print('------------------')
print(f'total = {total_cost:>9.3f}')
assert abs(autonomax.model.getObjective().getValue() - total_cost) < 1e-6
core = 6200.000 subnet = 10541.223 ------------------ total = 16741.223
visualization.show(pd.DataFrame(autonomax.city_info()), pd.DataFrame(autonomax.edge_info()))